package com.zenithmind.library.controller;

import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import com.zenithmind.library.pojo.dto.BookAuthorCreateDTO;
import com.zenithmind.library.pojo.query.BookAuthorQuery;
import com.zenithmind.library.pojo.vo.BookAuthorVO;
import com.zenithmind.library.service.BookAuthorService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 图书作者关联管理控制器
 * 遵循单一职责原则：只负责图书作者关联相关的HTTP请求处理
 * 遵循依赖倒置原则：依赖抽象接口而非具体实现
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@Slf4j
@RestController
@RequestMapping("/api/library/book-authors")
@RequiredArgsConstructor
@Tag(name = "图书作者关联管理", description = "图书与作者关联关系的增删改查、统计等功能")
public class BookAuthorController {

    private final BookAuthorService bookAuthorService;

    @GetMapping("/page")
    @Operation(summary = "分页查询图书作者关联", description = "根据条件分页查询图书作者关联列表")
    @PreAuthorize("hasAuthority('library:book-author:query')")
    public Result<PageResult<BookAuthorVO>> getBookAuthorPage(@Valid BookAuthorQuery query) {
        log.info("分页查询图书作者关联，查询条件：{}", query);
        PageResult<BookAuthorVO> result = bookAuthorService.getBookAuthorPage(query);
        return Result.success(result);
    }

    @GetMapping("/book/{bookId}/authors")
    @Operation(summary = "查询图书的作者列表", description = "根据图书ID查询该图书的所有作者")
    @PreAuthorize("hasAuthority('library:book-author:query')")
    public Result<List<BookAuthorVO>> getAuthorsByBookId(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId) {
        log.info("查询图书的作者列表，图书ID：{}", bookId);
        return bookAuthorService.getAuthorsByBookId(bookId);
    }

    @GetMapping("/author/{authorId}/books")
    @Operation(summary = "查询作者的图书列表", description = "根据作者ID查询该作者的所有图书")
    @PreAuthorize("hasAuthority('library:book-author:query')")
    public Result<List<BookAuthorVO>> getBooksByAuthorId(
            @Parameter(description = "作者ID", required = true)
            @PathVariable String authorId) {
        log.info("查询作者的图书列表，作者ID：{}", authorId);
        return bookAuthorService.getBooksByAuthorId(authorId);
    }

    @PostMapping("/book/{bookId}/author/{authorId}")
    @Operation(summary = "为图书添加作者", description = "为指定图书添加作者关联")
    @PreAuthorize("hasAuthority('library:book-author:create')")
    public Result<BookAuthorVO> addAuthorToBook(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId,
            @Parameter(description = "作者ID", required = true)
            @PathVariable String authorId,
            @Parameter(description = "作者角色")
            @RequestParam(required = false) String authorRole,
            @Parameter(description = "作者顺序")
            @RequestParam(required = false) Integer authorOrder) {
        log.info("为图书添加作者，图书ID：{}，作者ID：{}，角色：{}，顺序：{}", bookId, authorId, authorRole, authorOrder);
        return bookAuthorService.addAuthorToBook(bookId, authorId, authorRole, authorOrder);
    }

    @PostMapping("/book/{bookId}/authors/batch")
    @Operation(summary = "批量为图书添加作者", description = "为指定图书批量添加作者关联")
    @PreAuthorize("hasAuthority('library:book-author:create')")
    public Result<List<BookAuthorVO>> batchAddAuthorsToBook(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId,
            @Parameter(description = "作者关联列表", required = true)
            @RequestBody List<BookAuthorCreateDTO> bookAuthors) {
        log.info("批量为图书添加作者，图书ID：{}，数量：{}", bookId, bookAuthors.size());
        return bookAuthorService.batchAddAuthorsToBook(bookId, bookAuthors);
    }

    @DeleteMapping("/book/{bookId}/author/{authorId}")
    @Operation(summary = "从图书中移除作者", description = "从指定图书中移除作者关联")
    @PreAuthorize("hasAuthority('library:book-author:delete')")
    public Result<Void> removeAuthorFromBook(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId,
            @Parameter(description = "作者ID", required = true)
            @PathVariable String authorId) {
        log.info("从图书中移除作者，图书ID：{}，作者ID：{}", bookId, authorId);
        return bookAuthorService.removeAuthorFromBook(bookId, authorId);
    }

    @DeleteMapping("/book/{bookId}/authors/batch")
    @Operation(summary = "批量从图书中移除作者", description = "从指定图书中批量移除作者关联")
    @PreAuthorize("hasAuthority('library:book-author:delete')")
    public Result<Void> batchRemoveAuthorsFromBook(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId,
            @Parameter(description = "作者ID列表", required = true)
            @RequestBody List<String> authorIds) {
        log.info("批量从图书中移除作者，图书ID：{}，数量：{}", bookId, authorIds.size());
        return bookAuthorService.batchRemoveAuthorsFromBook(bookId, authorIds);
    }

    @PutMapping("/book/{bookId}/author/{authorId}")
    @Operation(summary = "更新图书作者关联", description = "更新图书作者关联信息")
    @PreAuthorize("hasAuthority('library:book-author:update')")
    public Result<BookAuthorVO> updateBookAuthor(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId,
            @Parameter(description = "作者ID", required = true)
            @PathVariable String authorId,
            @Parameter(description = "作者角色")
            @RequestParam(required = false) String authorRole,
            @Parameter(description = "作者顺序")
            @RequestParam(required = false) Integer authorOrder) {
        log.info("更新图书作者关联，图书ID：{}，作者ID：{}，角色：{}，顺序：{}", bookId, authorId, authorRole, authorOrder);
        return bookAuthorService.updateBookAuthor(bookId, authorId, authorRole, authorOrder);
    }

    @GetMapping("/book/{bookId}/primary-author")
    @Operation(summary = "获取图书主要作者", description = "获取指定图书的主要作者")
    @PreAuthorize("hasAuthority('library:book-author:query')")
    public Result<BookAuthorVO> getPrimaryAuthor(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId) {
        log.info("获取图书主要作者，图书ID：{}", bookId);
        return bookAuthorService.getPrimaryAuthor(bookId);
    }

    @PutMapping("/book/{bookId}/primary-author/{authorId}")
    @Operation(summary = "设置图书主要作者", description = "设置指定图书的主要作者")
    @PreAuthorize("hasAuthority('library:book-author:update')")
    public Result<Void> setPrimaryAuthor(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId,
            @Parameter(description = "作者ID", required = true)
            @PathVariable String authorId) {
        log.info("设置图书主要作者，图书ID：{}，作者ID：{}", bookId, authorId);
        return bookAuthorService.setPrimaryAuthor(bookId, authorId);
    }

    @PutMapping("/book/{bookId}/authors/order")
    @Operation(summary = "调整作者顺序", description = "调整指定图书的作者顺序")
    @PreAuthorize("hasAuthority('library:book-author:update')")
    public Result<Void> adjustAuthorOrder(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId,
            @Parameter(description = "作者顺序列表", required = true)
            @RequestBody List<BookAuthorService.AuthorOrderDTO> authorOrders) {
        log.info("调整作者顺序，图书ID：{}，数量：{}", bookId, authorOrders.size());
        return bookAuthorService.adjustAuthorOrder(bookId, authorOrders);
    }

    @PostMapping("/book/{sourceBookId}/copy-to/{targetBookId}")
    @Operation(summary = "复制图书作者关联", description = "将源图书的作者关联复制到目标图书")
    @PreAuthorize("hasAuthority('library:book-author:create')")
    public Result<List<BookAuthorVO>> copyBookAuthors(
            @Parameter(description = "源图书ID", required = true)
            @PathVariable String sourceBookId,
            @Parameter(description = "目标图书ID", required = true)
            @PathVariable String targetBookId) {
        log.info("复制图书作者关联，源图书ID：{}，目标图书ID：{}", sourceBookId, targetBookId);
        return bookAuthorService.copyBookAuthors(sourceBookId, targetBookId);
    }

    @GetMapping("/author/{authorId}/statistics")
    @Operation(summary = "获取作者图书统计", description = "获取指定作者的图书统计信息")
    @PreAuthorize("hasAuthority('library:book-author:query')")
    public Result<BookAuthorService.AuthorBookStatisticsVO> getAuthorBookStatistics(
            @Parameter(description = "作者ID", required = true)
            @PathVariable String authorId) {
        log.info("获取作者图书统计，作者ID：{}", authorId);
        return bookAuthorService.getAuthorBookStatistics(authorId);
    }

    @GetMapping("/book/{bookId}/statistics")
    @Operation(summary = "获取图书作者统计", description = "获取指定图书的作者统计信息")
    @PreAuthorize("hasAuthority('library:book-author:query')")
    public Result<BookAuthorService.BookAuthorStatisticsVO> getBookAuthorStatistics(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId) {
        log.info("获取图书作者统计，图书ID：{}", bookId);
        return bookAuthorService.getBookAuthorStatistics(bookId);
    }

    @GetMapping("/book/{bookId}/author/{authorId}/exists")
    @Operation(summary = "检查图书作者关联是否存在", description = "检查指定图书和作者的关联是否存在")
    @PreAuthorize("hasAuthority('library:book-author:query')")
    public Result<Boolean> checkBookAuthorExists(
            @Parameter(description = "图书ID", required = true)
            @PathVariable String bookId,
            @Parameter(description = "作者ID", required = true)
            @PathVariable String authorId) {
        log.info("检查图书作者关联是否存在，图书ID：{}，作者ID：{}", bookId, authorId);
        boolean exists = bookAuthorService.existsBookAuthor(bookId, authorId);
        return Result.success(exists);
    }

    @PostMapping("/import")
    @Operation(summary = "导入图书作者关联", description = "批量导入图书作者关联数据")
    @PreAuthorize("hasAuthority('library:book-author:import')")
    public Result<String> importBookAuthors(
            @Parameter(description = "图书作者关联数据列表", required = true)
            @RequestBody List<BookAuthorCreateDTO> bookAuthors) {
        log.info("导入图书作者关联，数量：{}", bookAuthors.size());
        return bookAuthorService.importBookAuthors(bookAuthors);
    }

    @PostMapping("/export")
    @Operation(summary = "导出图书作者关联", description = "根据条件导出图书作者关联数据")
    @PreAuthorize("hasAuthority('library:book-author:export')")
    public Result<String> exportBookAuthors(@RequestBody BookAuthorQuery query) {
        log.info("导出图书作者关联，查询条件：{}", query);
        return bookAuthorService.exportBookAuthors(query);
    }
}
